package com.shelpe.services.sinbad.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shelpe.services.sinbad.entity.jpa.ContainerSetting;
import com.shelpe.services.sinbad.entity.jpa.User;
import com.shelpe.services.sinbad.repository.jpa.ContainerSettingRepository;
import com.shelpe.services.sinbad.repository.jpa.UserRepository;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Controller
@RequestMapping("/sinbadservice/users")
@Slf4j
@Api(value = "设置相关的API", consumes = "application/json")
public class SettingsController {
	@Autowired
	private ContainerSettingRepository containerSettingRepository;
	@Autowired
	private UserRepository userRepository;
	@Autowired
	@JsonProperty
	private ObjectMapper objectMapper;

	@ApiOperation(value = "创建单项设置")
	@RequestMapping(method = RequestMethod.POST, path = "/{user_id}/containerSettings")
	@ResponseBody
	public SettingDto createContainerSetting(@PathVariable("user_id") long userID, @RequestBody SettingDto dto) {
		User user = this.userRepository.findOne(userID);
		Assert.notNull(user, "user_not_found");
		ContainerSetting setting = new ContainerSetting();
		BeanUtils.copyProperties(dto, setting);
		setting.setUserID(userID);
		setting.setSettingValues(dto.getSettingValues());
		setting.setCreateTime(new Date());
		setting.setLastModifiedTime(new Date());
		this.containerSettingRepository.save(setting);
		log.info("finish create setings:{}--{}", userID, setting);
		return dto;
	}

	@ApiOperation(value = "修改单项设置")
	@RequestMapping(method = RequestMethod.PUT, path = "/{user_id}/containerSettings/{key}")
	@ResponseBody
	public SettingDto updateContainerSetting(@PathVariable("user_id") long userID, @PathVariable("key") String key,
			@RequestParam("container_id") long containerID, @RequestParam("container_type") String type,
			@RequestBody SettingDto dto) {
		ContainerSetting setting = this.containerSettingRepository
				.findByUserIDAndSettingKeyAndContainerIDAndContainerType(userID, key, containerID, type);
		if (setting == null) {
			setting = new ContainerSetting();
			setting.setContainerID(containerID);
			setting.setUserID(userID);
			setting.setContainerType(type);
			setting.setCreateTime(new Date());
			setting.setSettingKey(key);
			log.info("finish create setings:{}--{}", userID, setting);
		}

		setting.setLastModifiedTime(new Date());
		setting.setSettingValues(dto.getSettingValues());

		this.containerSettingRepository.save(setting);
		BeanUtils.copyProperties(setting, dto);

		return dto;
	}

	@ApiOperation(value = "查看单项/多项设置")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "container_type", defaultValue = "user", allowableValues = "user", paramType = "query", dataType = "string") })
	@RequestMapping(method = RequestMethod.GET, path = "/{user_id}/containerSettings/@batch")
	@ResponseBody
	public List<SettingDto> findContainerSetting(@PathVariable("user_id") long userID,
			@RequestParam(name = "container_id") long containerID,
			@RequestParam(name = "key", required = false) String key,
			@RequestParam(name = "container_type", defaultValue = "user") String type) {

		List<SettingDto> dtos = new ArrayList<SettingDto>();
		if (StringUtils.isEmpty(key)) {
			List<ContainerSetting> settings = this.containerSettingRepository
					.findByUserIDAndContainerIDAndContainerType(userID, containerID, type);
			for (ContainerSetting setting : settings) {
				SettingDto dto = new SettingDto();
				BeanUtils.copyProperties(setting, dto);
				dtos.add(dto);
			}
		} else {
			ContainerSetting setting = this.containerSettingRepository
					.findByUserIDAndSettingKeyAndContainerIDAndContainerType(userID, key, containerID, type);
			SettingDto dto = new SettingDto();
			if (setting != null) {
				BeanUtils.copyProperties(setting, dto);
				dtos.add(dto);
			}
		}
		log.debug("finish find settings:{}", dtos);
		return dtos;
	}

	@Data
	@JsonInclude(Include.NON_DEFAULT)
	public static class SettingDto {
		@JsonProperty("setting_key")
		private String settingKey;
		@JsonProperty("container_id")
		private long containerID;
		@JsonProperty("container_type")
		private String containerType;
		@JsonProperty("setting_values")
		private String settingValues;

		// below findSetting to need
		@JsonFormat(shape = Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
		@JsonProperty("last_modified_time")
		private Date lastModifiedTime;
	}
}
